Removing an old, cherished, yet pointless caveat "This documentation is
[supercollider.git] / Help / Streams-Patterns-Events / A Practical Guide / PG_06a_Repetition_Contraint_Patterns.html
bloba74976b1138079dd419544e198b4866c3f9f6646
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta http-equiv="Content-Style-Type" content="text/css">
6 <title></title>
7 <meta name="Generator" content="Cocoa HTML Writer">
8 <meta name="CocoaVersion" content="824.48">
9 <style type="text/css">
10 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
11 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
12 p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
13 p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
14 p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #bf0000}
15 p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
16 p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0000bf}
17 p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #007300}
18 p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
19 p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #0000bf}
20 span.s1 {color: #0000bf}
21 span.s2 {color: #000000}
22 span.s3 {color: #007300}
23 span.s4 {color: #606060}
24 span.s5 {font: 12.0px Helvetica}
25 span.Apple-tab-span {white-space:pre}
26 </style>
27 </head>
28 <body>
29 <p class="p1"><b>Repetition and Constraint patterns</b></p>
30 <p class="p2"><br></p>
31 <p class="p3">These are essentially flow of control patterns. Each one takes a source pattern and repeats values from it, or stops the stream early based on a preset constraint.</p>
32 <p class="p2"><br></p>
33 <p class="p4"><b>Repetition patterns</b></p>
34 <p class="p2"><br></p>
35 <p class="p3">These patterns allow you to repeat single values, or (in the case of Pn) entire patterns.</p>
36 <p class="p2"><br></p>
37 <ul>
38 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pclutch(pattern, connected):</b> If the 'connected' pattern is true, <a href="../Patterns/Pclutch.html"><span class="s1">Pclutch</span></a> returns the next value from 'pattern'. If 'connected' is false, the previous pattern value is repeated. It's like a clutch in a car: when engaged, the pattern moves forward; when disconnected, it stays where it is.</li>
39 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pn(pattern, repeats):</b> Embeds the source pattern 'repeats' times: simple repetition. This also works on single values: Pn(1, 5) outputs the number 1 5 times.</li>
40 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pstutter(n, pattern):</b> 'n' and 'pattern' are both patterns. Each value from 'pattern' is repeated 'n' times. If 'n' is a pattern, each value can be repeated a different number of times.</li>
41 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>PdurStutter(n, pattern):</b> Like Pstutter, except the pattern value is divided by the number of repeats (so that the total time for the repeat cycle is the duration value from the source pattern).</li>
42 </ul>
43 <p class="p2"><br></p>
44 <p class="p3">See also <a href="../Patterns/Pstep.html"><span class="s1">Pstep</span></a>, described in <a href="PG_06b_Time_Based_Patterns.html"><span class="s1">PG_06b_Time_Based_Patterns</span></a>. Pstep can be used like <a href="../Patterns/Pstutter.html"><span class="s1">Pstutter</span></a>, but repetition is controlled by time rather than number of repeats per item.</p>
45 <p class="p2"><br></p>
46 <p class="p2"><br></p>
47 <p class="p5">// play repeated notes with a different rhythmic value per new pitch</p>
48 <p class="p5">// using Pstutter</p>
49 <p class="p6">p = <span class="s1">Pbind</span>(</p>
50 <p class="p5"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// making 'n' a separate stream so that degree and dur can share it</p>
51 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\n</span>, <span class="s1">Pwhite</span>(3, 10, <span class="s1">inf</span>),</p>
52 <p class="p7"><span class="s2"><span class="Apple-tab-span"> </span></span><span class="s3">\degree</span><span class="s2">, </span>Pstutter<span class="s2">(</span>Pkey<span class="s2">(</span><span class="s3">\n</span><span class="s2">), </span>Pwhite<span class="s2">(-4, 11, </span>inf<span class="s2">)),</span></p>
53 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\dur</span>, <span class="s1">Pstutter</span>(<span class="s1">Pkey</span>(<span class="s3">\n</span>), <span class="s1">Pwhite</span>(0.1, 0.4, <span class="s1">inf</span>)),</p>
54 <p class="p8"><span class="s2"><span class="Apple-tab-span"> </span></span>\legato<span class="s2">, 0.3</span></p>
55 <p class="p6">).play;</p>
56 <p class="p9"><br></p>
57 <p class="p6">p.stop;</p>
58 <p class="p9"><br></p>
59 <p class="p9"><br></p>
60 <p class="p5">// using Pfin / Pn</p>
61 <p class="p5">// Pn loops the Pbind infinitely</p>
62 <p class="p5">// Plazy builds a new Pbind for each iteration</p>
63 <p class="p5">// Pfin cuts off the Pbind when it's time for a new value</p>
64 <p class="p9"><br></p>
65 <p class="p6">p = <span class="s1">Pn</span>(</p>
66 <p class="p7"><span class="s2"><span class="Apple-tab-span"> </span></span>Plazy<span class="s2"> {</span></p>
67 <p class="p7"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>Pbind<span class="s2">(</span></p>
68 <p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">\degree</span>, <span class="s1">Pfin</span>(rrand(3, 10), rrand(-4, 11)),</p>
69 <p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s3">\dur</span>, rrand(0.1, 0.4)<span class="Apple-converted-space"> </span></p>
70 <p class="p6"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span>)</p>
71 <p class="p6"><span class="Apple-tab-span"> </span>},</p>
72 <p class="p7"><span class="s2"><span class="Apple-tab-span"> </span></span>inf</p>
73 <p class="p6">).play;</p>
74 <p class="p9"><br></p>
75 <p class="p6">p.stop;</p>
76 <p class="p9"><br></p>
77 <p class="p9"><br></p>
78 <p class="p5">// using Pclutch</p>
79 <p class="p5">// the rule is, when degree changes, dur should change also</p>
80 <p class="p5">// if Pdiff returns 0, degree has not changed</p>
81 <p class="p5">// so here, nonzero Pdiff values "connect" the clutch and allow a new dur to be generated</p>
82 <p class="p5">// otherwise the old one is held</p>
83 <p class="p6">p = <span class="s1">Pbind</span>(</p>
84 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\degree</span>, <span class="s1">Pstutter</span>(<span class="s1">Pwhite</span>(3, 10, <span class="s1">inf</span>), <span class="s1">Pwhite</span>(-4, 11, <span class="s1">inf</span>)),</p>
85 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\dur</span>, <span class="s1">Pclutch</span>(<span class="s1">Pwhite</span>(0.1, 0.4, <span class="s1">inf</span>), <span class="s1">Pdiff</span>(<span class="s1">Pkey</span>(<span class="s3">\degree</span>)).abs &gt; 0),</p>
86 <p class="p8"><span class="s2"><span class="Apple-tab-span"> </span></span>\legato<span class="s2">, 0.3</span></p>
87 <p class="p6">).play;</p>
88 <p class="p9"><br></p>
89 <p class="p6">p.stop;</p>
90 <p class="p9"><br></p>
91 <p class="p9"><br></p>
92 <p class="p4"><b>Constraint (or interruption) patterns</b></p>
93 <p class="p2"><br></p>
94 <p class="p3">Instead of prolonging a stream by repetition, these patterns use different methods to stop a stream dynamically. They are especially useful for modularizing pattern construction. One section of your code might be responsible for generating numeric or event patterns. By using constraint patterns, that part of the code doesn't have to know how many events or how long to play. It can just return an infinite pattern, and another part of the code can wrap it in one of these to stop it based on the appropriate condition.</p>
95 <p class="p2"><br></p>
96 <ul>
97 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pfin(count, pattern): </b>Returns exactly 'count' values from the source pattern, then stops. (<a href="../Patterns/Pfin.html"><span class="s1">Pfin</span></a> has a cousin, Pfinval, that is deprecated.)</li>
98 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pconst(sum, pattern, tolerance):</b> Output numbers until the sum goes over a predefined limit. The last output value is adjusted so that the sum matches the limit exactly.</li>
99 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Pfindur(dur, pattern, tolerance):</b> Like Pconst, but applying the "constrain" behavior to the event's rhythmic values. The source pattern runs up to the specified duration, then stops. This is very useful if you know how long a musical behavior should go on, but the number of events to fill up that time is not known.</li>
100 </ul>
101 <p class="p2"><br></p>
102 <p class="p5">// Two variants on the same thing</p>
103 <p class="p5">// Use Pconst or Pfindur to create 4-beat segments with randomized rhythm</p>
104 <p class="p5">// Pconst and Pfindur both can ensure the total rhythm doesn't go above 4.0</p>
105 <p class="p9"><br></p>
106 <p class="p7"><span class="s2">p = </span>Pn<span class="s2">(</span>Pbind<span class="s2">(</span></p>
107 <p class="p5"><span class="s2"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// always a low C on the downbeat</p>
108 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\degree</span>, <span class="s1">Pseq</span>([-7, <span class="s1">Pwhite</span>(0, 11, <span class="s1">inf</span>)], 1),</p>
109 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\dur</span>, <span class="s1">Pconst</span>(4, <span class="s1">Pwhite</span>(1, 4, <span class="s1">inf</span>) * 0.25)</p>
110 <p class="p6">), <span class="s1">inf</span>).play;</p>
111 <p class="p9"><br></p>
112 <p class="p6">p.stop;</p>
113 <p class="p9"><br></p>
114 <p class="p7"><span class="s2">p = </span>Pn<span class="s2">(</span>Pfindur<span class="s2">(4, </span>Pbind<span class="s2">(</span></p>
115 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\degree</span>, <span class="s1">Pseq</span>([-7, <span class="s1">Pwhite</span>(0, 11, <span class="s1">inf</span>)], 1),</p>
116 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\dur</span>, <span class="s1">Pwhite</span>(1, 4, <span class="s1">inf</span>) * 0.25</p>
117 <p class="p6">)), <span class="s1">inf</span>).play;</p>
118 <p class="p9"><br></p>
119 <p class="p6">p.stop;</p>
120 <p class="p2"><br></p>
121 <p class="p2"><br></p>
122 <ul>
123 <li style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica"><b>Psync(pattern, quant, maxdur, tolerance):</b> Like Pfindur, but does not have a fixed duration limit. Instead, it plays until either it reaches maxdur (in which case it behaves like Pfindur, adjusting the last event so the total duration matches maxdur), or the pattern stops early and the last event is rounded up to the next integer multiple of quant. This is hard to explain; a couple of examples might make it clearer.</li>
124 </ul>
125 <p class="p2"><br></p>
126 <p class="p6">(</p>
127 <p class="p5">// in this case, the pattern stops by reaching maxdur</p>
128 <p class="p5">// elapsed time = 4</p>
129 <p class="p6"><span class="s1">var</span><span class="Apple-tab-span"> </span>startTime;</p>
130 <p class="p7"><span class="s2">p = (</span>Psync<span class="s2">(</span>Pbind<span class="s2">(</span></p>
131 <p class="p5"><span class="s2"><span class="Apple-tab-span"> </span></span><span class="s3">\dur</span><span class="s2">, 0.25,<span class="Apple-tab-span"> </span></span>// total duration = infinite</p>
132 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\time</span>, <span class="s1">Pfunc</span> { startTime = startTime ? (<span class="s1">thisThread</span>.clock.beats.debug(<span class="s4">"time"</span>)) }</p>
133 <p class="p6">), 1, 4) ++ <span class="s1">Pfuncn</span>({</p>
134 <p class="p6"><span class="Apple-tab-span"> </span><span class="s1">thisThread</span>.clock.beats.debug(<span class="s4">"finish time"</span>);</p>
135 <p class="p6"><span class="Apple-tab-span"> </span>(<span class="s1">thisThread</span>.clock.beats - startTime).debug(<span class="s4">"elapsed"</span>);</p>
136 <p class="p7"><span class="s2"><span class="Apple-tab-span"> </span></span>nil</p>
137 <p class="p6">}, 1)).play;</p>
138 <p class="p6">)</p>
139 <p class="p9"><br></p>
140 <p class="p6">(</p>
141 <p class="p5">// in this case, the pattern stops itself before maxdur (4)</p>
142 <p class="p5">// the Pbind's duration (1.25) gets rounded up to 2 (next multiple of 1)</p>
143 <p class="p6"><span class="s1">var</span><span class="Apple-tab-span"> </span>startTime;</p>
144 <p class="p7"><span class="s2">p = (</span>Psync<span class="s2">(</span>Pbind<span class="s2">(</span></p>
145 <p class="p5"><span class="s2"><span class="Apple-tab-span"> </span></span><span class="s3">\dur</span><span class="s2">, </span><span class="s1">Pn</span><span class="s2">(0.25, 5),<span class="Apple-tab-span"> </span></span>// total duration = 0.25 * 5 = 1.25</p>
146 <p class="p6"><span class="Apple-tab-span"> </span><span class="s3">\time</span>, <span class="s1">Pfunc</span> { startTime = startTime ? (<span class="s1">thisThread</span>.clock.beats.debug(<span class="s4">"time"</span>)) }</p>
147 <p class="p6">), 1, 4) ++ <span class="s1">Pfuncn</span>({</p>
148 <p class="p6"><span class="Apple-tab-span"> </span><span class="s1">thisThread</span>.clock.beats.debug(<span class="s4">"finish time"</span>);</p>
149 <p class="p6"><span class="Apple-tab-span"> </span>(<span class="s1">thisThread</span>.clock.beats - startTime).debug(<span class="s4">"elapsed"</span>);</p>
150 <p class="p7"><span class="s2"><span class="Apple-tab-span"> </span></span>nil</p>
151 <p class="p6">}, 1)).play;</p>
152 <p class="p6">)</p>
153 <p class="p2"><br></p>
154 <p class="p2"><br></p>
155 <p class="p10"><span class="s2">Previous:<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><a href="PG_060_Filter_Patterns.html"><span class="s5">PG_060_Filter_Patterns</span></a></span></p>
156 <p class="p10"><span class="s2">Next:<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><a href="PG_06b_Time_Based_Patterns.html"><span class="s5">PG_06b_Time_Based_Patterns</span></a></span></p>
157 </body>
158 </html>